﻿using System.Buffers;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
using eNets.CBK.Pipe;
using eNets.CBK.Sockets;

namespace eNets.CBK.Session.Tcp;

sealed partial class TcpSession : ASession
{
    public TcpSession(Socket socket, MemoryPool<byte> memoryPool) : base(socket)
    {
        var bufScheduler = ThreadSchedulerAllotter.BufAllotter.Next();
        var sktScheduler = ThreadSchedulerAllotter.SktAllotter.Next();
        this.rcvPipe = PipeProvider.CreateStandardPipe(memoryPool, bufScheduler);
        this.sndPipe = PipeProvider.CreateStandardPipe(memoryPool, bufScheduler);
        this.rcvOper = SocketProvider.CreateTcpRcvOper(socket, sktScheduler, this.OnSocketRcvCompleted);
        this.sndOper = SocketProvider.CreateTcpSndOper(socket, sktScheduler, this.OnSocketSndCompleted);
    }

    private long active;
    
    public override bool Active
    {
        get { return Volatile.Read(ref this.active) == 1; }
    }

    public override ValueTask StartAsync()
    {
        Volatile.Write(ref this.active, 1);
        this.RcvStartAsync();
        this.SndStartAsync();
        
        return new ValueTask();
    }

    public override ValueTask CloseAsync()
    {
        Volatile.Write(ref this.active, 0);
        this.rcvOper.Dispose();
        this.sndOper.Dispose();
        
        return base.CloseAsync();
    }
}